﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Net;

namespace RSSReader
{
    public delegate void ReadItemsDelegate(TreeNode node, RssChannel channel);


    public enum ReadType
    {
        /// <summary>
        /// ReadToDescendant Method를 사용합니다.
        /// </summary>
        Descendant,
        /// <summary>
        /// ReadToNextSibling Method를 사용합니다.
        /// </summary>
        NextSibling,
        /// <summary>
        /// ReadToFollowing Method를 사용합니다.
        /// </summary>
        Following
    }

    public sealed class RSSFunctions
    {
        /// <summary>
        /// 리스트 저장
        /// </summary>
        /// <param name="sNewUrl">신규로 추가할 Url</param>
        public static bool WriteDataXml(List<RssChannel> urlList, string xmlFileName, int updateTime)
        {
            XmlTextWriter writer = null;

            try
            {
                //XmlTextWriter 개체 생성
                writer = new XmlTextWriter(xmlFileName, Encoding.UTF8);
                //들여쓰기 설정
                writer.Formatting = Formatting.Indented;
                writer.Indentation = 4;

                //list.xml 파일
                writer.WriteStartDocument();
                writer.WriteStartElement("list");
                writer.WriteElementString("name", "RssList");
                writer.WriteElementString("reloadTime", updateTime.ToString());

                //각 요소에 포함된 반복문을 돌려줍니다. (list배열에 포함된 url)
                foreach (RssChannel item in urlList)
                {
                    writer.WriteStartElement("url");
                    writer.WriteElementString("title", item.Title);
                    writer.WriteElementString("link", item.Link);
                    writer.WriteElementString("description", item.Description);
                    writer.WriteElementString("lastPost", item.LastPost);
                    writer.WriteEndElement();
                }

                writer.WriteEndElement();
                writer.WriteEndDocument();
                writer.Close();
            }
            catch (Exception ex)
            {
                if (writer != null)
                    writer.Close();

                MessageBox.Show(ex.Message, ex.Source, MessageBoxButtons.OK, MessageBoxIcon.Error);

                return false;
            }

            return true;
        }

        public static void ReadItems(TreeNode node, RssChannel channel)
        {
            XmlTextReader reader = new XmlTextReader(channel.Link);
            node.Nodes.Clear();

            try
            {
                if (reader.ReadToFollowing("rss"))
                {
                    while (reader.ReadToFollowing("item"))
                        if (IsElement(reader, "item"))
                            node.Nodes.Add(GetTreeNode(reader));
                }
            }
            catch (Exception)
            {
                reader.Close();
            }

            reader.Close();
        }

        public static void MoveAndRead(XmlReader reader, ReadType type, string name, ref string target)
        {
            switch(type)
            {
                case ReadType.Descendant:
                    if (reader.ReadToDescendant(name))
                        target = reader.ReadString();
                    break;
                case ReadType.NextSibling:
                    if (reader.ReadToNextSibling(name))
                        target = reader.ReadString();
                    break;
                case ReadType.Following:
                    if (reader.ReadToFollowing(name))
                        target = reader.ReadString();
                    break;
            }            
        }

        public static string CheckAndRead(XmlReader reader, string name)
        {
            if (reader.Name == name && reader.NodeType == System.Xml.XmlNodeType.Element)
                return reader.ReadString();
            return "";
        }

        public static void CheckAndRead(XmlReader reader, string name, ref string target)
        {
            if (reader.Name == name && reader.NodeType == System.Xml.XmlNodeType.Element)
                target = reader.ReadString();
        }

        private static TreeNode GetTreeNode(XmlReader reader)
        {
            TreeNode node = new TreeNode();
            XmlReader subReader = reader.ReadSubtree();
            subReader.Read();
            node.ImageIndex = 1;
            node.SelectedImageIndex = -1;

            if (subReader.ReadToDescendant("title"))
                node.Text = subReader.ReadString();

            if (subReader.ReadToNextSibling("link"))
                node.Name = subReader.ReadString();

            if (subReader.ReadToNextSibling("description"))
                node.Tag = subReader.ReadString();

            return node;
        }

        private static bool IsElement(XmlReader reader, string name)
        {
            if (reader.Name == name && reader.NodeType == System.Xml.XmlNodeType.Element)
                return true;

            return false;
        }

        private static bool HasChild(TreeNode node)
        {
            if (node.Nodes.Count != 0 &&
                node.Nodes[0].Name != null &&
                node.Nodes[0].Name.ToString() != "")
                return true;

            return false;
        }
    }
}
